using System;
using System.Runtime.InteropServices;

namespace Leap
{
	public class Interface : IDisposable
	{
		public class Implementation : IDisposable
		{
			private HandleRef swigCPtr;

			protected bool swigCMemOwn;

			public Implementation(IntPtr cPtr, bool cMemoryOwn)
			{
				swigCMemOwn = cMemoryOwn;
				swigCPtr = new HandleRef(this, cPtr);
			}

			public static HandleRef getCPtr(Implementation obj)
			{
				return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
			}

			~Implementation()
			{
				Dispose();
			}

			public virtual void Dispose()
			{
				lock (this)
				{
					if (swigCPtr.Handle != IntPtr.Zero)
					{
						if (swigCMemOwn)
						{
							swigCMemOwn = false;
							LeapPINVOKE.delete_Interface_Implementation(swigCPtr);
						}
						swigCPtr = new HandleRef(null, IntPtr.Zero);
					}
					GC.SuppressFinalize(this);
				}
			}

			public Implementation()
				: this(LeapPINVOKE.new_Interface_Implementation(), true)
			{
			}
		}

		private HandleRef swigCPtr;

		protected bool swigCMemOwn;

		public Interface(IntPtr cPtr, bool cMemoryOwn)
		{
			swigCMemOwn = cMemoryOwn;
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(Interface obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		public virtual void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (swigCMemOwn)
					{
						swigCMemOwn = false;
						throw new MethodAccessException("C++ destructor does not have public access");
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
			}
		}
	}
}
